home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include <gl.h>
- #include <device.h>
- #include <math.h>
- #include <stdio.h>
- #include <string.h>
-
-
- #include "vect.h"
-
- #define USETMESH
-
- #define SPHERE 15
- #define SPRINGS 28
- #define VERTICES 8
-
- #define GRID 3
-
- #define GRIDXSIZE ((GRID)*2*4*4)
-
-
-
- #define Pack(r,g,b,a) ((int)(r) | ((int)(g) << 8) | ((int)(b) << 16) | ((int)(a) << 24))
-
- float vel[VERTICES][3], vert[VERTICES][3], tot_force[VERTICES][3],
- sdist[SPRINGS], sdist_last[SPRINGS],
- eye_ball[3],
- damp, stiff, mtime, mass, gravity, floor_damp, fric, blur,
- floor_z, ceiling_z;
-
- int sv1[SPRINGS], sv2[SPRINGS];
-
- static winxsize=0, winysize=0;
-
-
- float ident_mat[4][4] = { { 1, 0, 0, 0 },
- { 0, 1, 0, 0 },
- { 0, 0, 1, 0 },
- { 0, 0, 0, 1 } };
-
- int face[6][4] = { {0, 1, 5, 4},
- {3, 7, 6, 2},
- {3, 0, 4, 7},
- {2, 6, 5, 1},
- {0, 3, 2, 1},
- {4, 5, 6, 7} },
- norm_vert[6][4] = { {3, 2, 6, 7},
- {0, 4, 5, 1},
- {2, 1, 5, 6},
- {3, 7, 4, 0},
- {4, 7, 6, 5},
- {0, 1, 2, 3} },
- texture_coord[4][2] = { {0,0}, {1,0}, {1,1}, {0,1} },
- up[] = {0,0,1};
-
-
- int azim = -200, incl, fovy, win_x1, win_x2, win_y1, win_y2, win_w, win_h;
- float dist;
-
- float floordata[((GRID)*2)*((GRID)*2)*4*4];
-
-
- char cube[500], floor1[500], floor2[500], back_texture[500];
- int texcube=0, texfloor1=0, texfloor2=0;
-
-
- float matter1[] = { ALPHA, 0.7, LMNULL };
- float empty[] = { LMNULL };
-
-
- #ifdef SUBDIV
- float subdiv[] = { PD_MAX_SCREEN_Z, 500.0,
- PD_MIN_SCREEN_SIZE, 5.0,
- PD_NULL };
- #endif SUBDIV
-
-
- FILE *setup;
- char texdir[80];
- int texloc;
-
- int fullscreenmode = 0;
- int debugmode = 0;
-
- docmdline(argc, argv)
- int argc;
- char **argv;
- {
- int opt, err = 0;
- extern char *optarg;
- extern int getopt();
-
- while ((opt = getopt(argc,argv,"Dfs:t:?")) != -1) {
- switch(opt) {
- case 's':
- setup = fopen(optarg, "r");
- if (setup == 0) {
- fprintf(stderr, "blob: Can't open %s\n", optarg);
- exit(1);
- }
- break;
- case 'D':
- debugmode = 1;
- break;
- case 'f':
- fullscreenmode = 1;
- break;
- case 't':
- strcpy(texdir, optarg);
- texloc = 1;
- break;
- case '?':
- default:
- err++;
- break;
- }
- }
-
- if (setup == 0)
- err++;
-
- if (err) {
- printf("blob -s <setup_file>\n");
- exit(1);
- }
- }
-
- handledevice(dev, val)
- int dev;
- short val;
- {
- switch(dev) {
- case ESCKEY:
- if (val == 0) {
- gexit();
- exit(0);
- }
- break;
-
- case REDRAW:
- keepaspect(5,4);
- reshapeviewport();
- getsize(&winxsize, &winysize);
- drawscene();
- swapbuffers();
- break;
- default: break;
- }
- }
-
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int v, s, i, j, k, x, y;
- int tx, ty;
- float sqrt3;
- char tcube[80], tfloor1[80], tfloor2[80];
- int dev;
- short val;
-
- docmdline(argc, argv);
-
- fscanf(setup, " %i %i %i %i %s %d %s %d %s %d %s %f %f %f %f %f %f %f %f %f %f %i %i %f",
- &win_x1, &win_x2, &win_y1, &win_y2,
- tcube, &texcube, tfloor1, &texfloor1, tfloor2, &texfloor2,
- back_texture,
- &stiff, &damp, &mtime, &mass, &gravity,
- &floor_damp, &fric, &blur,
- &floor_z, &ceiling_z, &incl, &fovy, &dist);
-
- if (texloc) {
- strcpy(cube,texdir);
- strcat(cube,tcube);
- strcpy(floor1,texdir);
- strcat(floor1,tfloor1);
- strcpy(floor2,texdir);
- strcat(floor2,tfloor2);
- } else {
- strcpy(cube,tcube);
- strcpy(floor1,tfloor1);
- strcpy(floor2,tfloor2);
- }
-
- win_w = win_x2 - win_x1 + 1;
- win_h = win_y2 - win_y1 + 1;
-
- mtime = 1 / mtime;
- gravity *= 9.8;
-
- matter1[1] = blur / 255.0;
-
- for (v = 0; v < VERTICES; v++) {
- for (i = 0; i < 3; i++) {
- vel[v][i] = 0;
- }
- }
-
- sv1[0] = 0; sv2[0] = 1; sdist[0] = 1;
- sv1[1] = 1; sv2[1] = 5; sdist[1] = 1;
- sv1[2] = 5; sv2[2] = 4; sdist[2] = 1;
- sv1[3] = 4; sv2[3] = 0; sdist[3] = 1;
- sv1[4] = 3; sv2[4] = 2; sdist[4] = 1;
- sv1[5] = 2; sv2[5] = 6; sdist[5] = 1;
- sv1[6] = 6; sv2[6] = 7; sdist[6] = 1;
- sv1[7] = 7; sv2[7] = 3; sdist[7] = 1;
- sv1[8] = 0; sv2[8] = 3; sdist[8] = 1;
- sv1[9] = 4; sv2[9] = 7; sdist[9] = 1;
- sv1[10] = 5; sv2[10] = 6; sdist[10] = 1;
- sv1[11] = 1; sv2[11] = 2; sdist[11] = 1;
-
- sv1[12] = 0; sv2[12] = 5; sdist[12] = M_SQRT2;
- sv1[13] = 1; sv2[13] = 4; sdist[13] = M_SQRT2;
- sv1[14] = 3; sv2[14] = 6; sdist[14] = M_SQRT2;
- sv1[15] = 7; sv2[15] = 2; sdist[15] = M_SQRT2;
- sv1[16] = 0; sv2[16] = 7; sdist[16] = M_SQRT2;
- sv1[17] = 4; sv2[17] = 3; sdist[17] = M_SQRT2;
- sv1[18] = 1; sv2[18] = 6; sdist[18] = M_SQRT2;
- sv1[19] = 2; sv2[19] = 5; sdist[19] = M_SQRT2;
- sv1[20] = 4; sv2[20] = 6; sdist[20] = M_SQRT2;
- sv1[21] = 5; sv2[21] = 7; sdist[21] = M_SQRT2;
- sv1[22] = 0; sv2[22] = 2; sdist[22] = M_SQRT2;
- sv1[23] = 1; sv2[23] = 3; sdist[23] = M_SQRT2;
-
- sqrt3 = sqrt(3.0);
- sv1[24] = 0; sv2[24] = 6; sdist[24] = sqrt3;
- sv1[25] = 1; sv2[25] = 7; sdist[25] = sqrt3;
- sv1[26] = 2; sv2[26] = 4; sdist[26] = sqrt3;
- sv1[27] = 3; sv2[27] = 5; sdist[27] = sqrt3;
-
- for (s = 0; s < SPRINGS; s++)
- sdist_last[s] = sdist[s];
-
- vert[0][0] = 0.5;
- vert[0][1] = 0.5;
- vert[0][2] = -0.5;
-
- vert[1][0] = -0.5;
- vert[1][1] = 0.5;
- vert[1][2] = -0.5;
-
- vert[2][0] = -0.5;
- vert[2][1] = -0.5;
- vert[2][2] = -0.5;
-
- vert[3][0] = 0.5;
- vert[3][1] = -0.5;
- vert[3][2] = -0.5;
- vert[4][0] = 0.5;
- vert[4][1] = 0.5;
- vert[4][2] = 0.5;
- vert[5][0] = -0.5;
- vert[5][1] = 0.5;
- vert[5][2] = 0.5;
- vert[6][0] = -0.5;
- vert[6][1] = -0.5;
- vert[6][2] = 0.5;
- vert[7][0] = 0.5;
- vert[7][1] = -0.5;
- vert[7][2] = 0.5;
-
- vel[0][0] = 0.05;
- vel[6][0] = -0.05;
-
- for (i = 0; i < VERTICES; i++)
- vert[i][2] += 1.0;
-
- /* create floor data */
- for (i = -GRID, ty=0; i < GRID; i++, ty++) { /* row */
- for (j = -GRID, tx=0; j < GRID; j++, tx++) { /* poly in row */
- for (v=0; v < 4; v++) { /* vert in poly */
- /* compute and enter x,y for current vert */
- floordata[ty*GRIDXSIZE + tx*16 + v*4 + 0] =
- ((-GRID + ((texture_coord[v][0] + tx))) *3.0);
- floordata[ty*GRIDXSIZE + tx*16 + v*4 + 1] =
- ((-GRID + ((texture_coord[v][1] + ty))) *3.0);
- floordata[ty*GRIDXSIZE + tx*16 + v*4 + 2] = (floor_z - 0.01);
- }
- }
- }
-
- if (debugmode)
- foreground();
- if (fullscreenmode)
- prefposition(win_x1, win_x2, win_y1, win_y2);
-
- keepaspect(5,4);
- winopen("blob");
-
- glcompat(GLC_OLDPOLYGON, FALSE);
-
- qdevice(ESCKEY);
- qdevice(REDRAW);
-
- doublebuffer();
- RGBmode();
- zbuffer(0);
- backface(1);
- gconfig();
- clearscreen();
-
- /* readsource(SRC_BACK); */
- /* zbuffer(TRUE); */
-
- getsize(&winxsize, &winysize);
- mmode(MVIEWING);
- perspective(fovy, (float)winxsize / winxsize, 1, GRID * 12);
- loadmatrix(ident_mat);
-
- lmdef(DEFMATERIAL, 1, 0, matter1);
- lmdef(DEFLMODEL, 1, 0, empty);
- lmdef(DEFLIGHT, 1, 0, empty);
- lmdef(DEFLIGHT, 2, 0, empty);
- lmbind(LMODEL, 1);
- lmbind(LIGHT1, 1);
-
- #ifdef STAPUFT
- bind_texture(cube, 1, texcube);
- bind_texture(floor1, 2, texfloor1);
- bind_texture(floor2, 3, texfloor2);
-
- subpixel(TRUE);
- #endif STAPUFT
-
- show_blob();
- swapbuffers();
-
- while(1) {
- while (qtest()) {
- dev = qread(&val);
- handledevice(dev,val);
- }
- drawscene();
- swapbuffers();
- }
- }
-
- drawscene()
- {
- do_gravity();
- do_springs();
- do_move();
- do_floor();
- do_ceiling();
- show_blob();
- }
-
- show_blob()
- {
- int i, j, tx, ty;
- int even = 1;
-
- /* zbuffer(0);
- texbind(TX_TEXTURE_0, 0);
- drawback(back_texture);
- zbuffer(1);
- zclear();*/
-
- cpack(0x00331111);
- clear();
-
- pushmatrix();
- polarview(dist, azim, incl, 0);
- lmbind(LIGHT0, 2);
- azim += 7;
-
- #ifdef STAPUFT
-
- #ifdef SUBDIVd
- polysubdivide(PD_DEPTH, subdiv);
- #endif SUBDIV
-
-
- /* first draw all squares of floor 1 */
- texbind(TX_TEXTURE_0, 2);
- even = 1;
- cpack(Pack(255,255,255,blur));
- for (i = -GRID, ty=0; i < GRID; i++, ty++) {
-
- for (j = (-GRID + even), tx = even; j < GRID; j+=2, tx+=2) {
-
- bgnpolygon();
- t2i(texture_coord[0]);
- v3f(floordata + ty*GRIDXSIZE + tx*16 );
-
- t2i(texture_coord[1]);
- v3f(floordata + ty*GRIDXSIZE + tx*16 + 4);
-
- t2i(texture_coord[2]);
- v3f(floordata + ty*GRIDXSIZE + tx*16 + 8);
-
- t2i(texture_coord[3]);
- v3f(floordata + ty*GRIDXSIZE + tx*16 + 12);
-
- endpolygon();
- }
- even ^= 1;
- }
-
- /* then draw all squares of floor 1 */
- even = 0;
- texbind(TX_TEXTURE_0, 3);
- cpack(Pack(255,255,255,blur));
-
- for (i = -GRID, ty=0; i < GRID; i++, ty++) {
- static long c_toggle = 0, c;
-
- for (j = (-GRID + even), tx = even; j < GRID; j+=2, tx+=2) {
-
- bgnpolygon();
- t2i(texture_coord[0]);
- v3f(floordata + ty*GRIDXSIZE + tx*16 );
-
- t2i(texture_coord[1]);
- v3f(floordata + ty*GRIDXSIZE + tx*16 + 4);
-
- t2i(texture_coord[2]);
- v3f(floordata + ty*GRIDXSIZE + tx*16 + 8);
-
- t2i(texture_coord[3]);
- v3f(floordata + ty*GRIDXSIZE + tx*16 + 12);
-
- endpolygon();
- }
- even ^= 1;
- }
-
- #ifdef SUBDIV
- polysubdivide(0, 0);
- #endif SUBDIV
-
- #else STAPUFT
-
- pushmatrix();
- scale(3, 3, 1);
- translate(0, 0, floor_z - 0.01);
- shademodel(FLAT);
- for (i = -10; i < 10; i++) {
- static long c_toggle = 0;
-
- for (j = -10; j < 10; j++) {
-
- if (c_toggle % 2 == 0) {
- cpack(Pack(255, 80, 80, blur));
- } else {
- cpack(Pack(80,255,80, blur));
- }
-
- c_toggle = 1 - c_toggle;
- rectf(i, j, i+1, j+1);
- }
- c_toggle = 1 - c_toggle;
- }
- popmatrix();
- shademodel(GOURAUD);
- #endif STAPUFT
-
- draw_cube();
-
- popmatrix();
- }
-
-
- #define SHADOWS 5
-
- draw_cube()
- {
- float norm[3];
- int i, j, k, l;
- static int init = 1;
- static float rndx[5], rndy[5];
-
- if(init) {
- for (l=0; l < 5; l++) {
- rndx[l] = (float)(random() & 0xffff) / 65535 / 50.;
- rndy[l] = (float)(random() & 0xffff) / 65535 / 50.;
- }
- init = 0;
- }
-
- pushmatrix();
- translate(0,0,floor_z);
- scale(1., 1., 0.);
- texbind(0,0);
- blendfunction(BF_SA, BF_MSA);
- cpack(0x40000000);
- for (l=0; l < 5; l++) {
- translate(rndx[l], rndy[l], 0.);
- for (i = 0; i < 6; i++) {
- #ifdef USETMESH
- bgntmesh();
- for (j = 0; j < 4; j++) {
- if(j<2)
- k = j;
- else
- k = 5-j;
- v2f(vert[face[i][k]]);
- }
- endtmesh();
- #else
- bgnpolygon();
- v2f(vert[face[i][0]]);
- v2f(vert[face[i][1]]);
- v2f(vert[face[i][2]]);
- v2f(vert[face[i][3]]);
- endpolygon();
- #endif
- }
- }
-
- blendfunction(BF_ONE, BF_ZERO);
- popmatrix();
- zbuffer(TRUE);
- zclear();
-
- lmbind(MATERIAL, 1);
-
- #ifdef STAPUFT
- texbind(TX_TEXTURE_0, 1);
- #endif STAPUFT
-
- for (i = 0; i < 6; i++) {
- #ifdef USETMESH
- bgntmesh();
- for (j = 0; j < 4; j++) {
- if(j<2)
- k = j;
- else
- k = 5-j;
- vsub(vert[face[i][k]], vert[norm_vert[i][k]], norm);
- vnormal(norm);
- n3f(norm);
- #ifdef STAPUFT
- t2i(texture_coord[k]);
- #endif STAPUFT
- v3f(vert[face[i][k]]);
- }
- endtmesh();
- #else
- bgnpolygon();
- for (j = 0; j < 4; j++) {
- vsub(vert[face[i][j]], vert[norm_vert[i][j]], norm);
- vnormal(norm);
- n3f(norm);
- #ifdef STAPUFT
- t2i(texture_coord[j]);
- #endif STAPUFT
- v3f(vert[face[i][j]]);
- }
- endpolygon();
- #endif
- }
- lmbind(MATERIAL, 0);
- zbuffer(FALSE);
- }
-
-
-
-
- do_springs()
- {
- int i;
- float force_dir[3], damp_dir[3], dist;
-
-
- for (i = 0; i < SPRINGS; i++) {
- vsub(vert[sv2[i]], vert[sv1[i]], force_dir);
- vcopy(force_dir, damp_dir);
- dist = vlength(force_dir);
-
- vscale(force_dir, (dist - sdist[i]) * stiff);
-
- vadd(force_dir, tot_force[sv1[i]], tot_force[sv1[i]]);
- vsub(tot_force[sv2[i]], force_dir, tot_force[sv2[i]]);
-
- vscale(damp_dir, damp * (dist - sdist_last[i]) * mass);
- vadd(tot_force[sv1[i]], damp_dir, tot_force[sv1[i]]);
- vsub(tot_force[sv2[i]], damp_dir, tot_force[sv2[i]]);
-
- /* debug
- if (vlength(damp_dir) > fabs(dist - sdist_last[i]) * mass)
- printf("Damping too big, or mtime step too small\n");
- */
-
- sdist_last[i] = dist;
- }
- }
-
-
- do_move()
- {
- int i;
-
- for (i = 0; i < VERTICES; i++) {
- vscale(tot_force[i], mtime * (1/30.0) / mass);
-
- vadd(tot_force[i], vel[i], vel[i]);
- vadd(vert[i], vel[i], vert[i]);
- }
- }
-
-
- do_gravity()
- {
- int i;
-
- for (i = 0; i < VERTICES; i++) {
- vset(tot_force[i], 0.0, 0.0, -gravity * mass);
- }
- }
-
-
- do_floor()
- {
- int i;
-
- for (i = 0; i < VERTICES; i++) {
- if (vert[i][2] < floor_z) {
- vert[i][2] = floor_z;
- vel[i][2] = -vel[i][2] * (1 + floor_damp);
- }
- }
- }
-
- do_ceiling()
- {
- int i, j;
-
- for (i = 0; i < VERTICES; i++) {
- if (vert[i][2] > ceiling_z) {
- vert[i][2] = ceiling_z;
- for (j = 0; j < VERTICES; j++) {
- vel[j][2] = 0;
- }
- }
- }
- }
-
- clearscreen()
- {
- cpack(0x00808080);
- clear();
- swapbuffers();
- }
-